package experimentThird;

import lombok.Data;

import java.util.LinkedList;

@Data
class MemoryManager {
    private Partition head; // 空闲分区链的头节点
    private Partition lastAllocated; // 上一次分配结束的位置（用于循环首次适应算法）

    public MemoryManager(int totalSize) {
        head = new Partition(0, totalSize, true);
        lastAllocated = head;
    }

    // 显示当前空闲分区链的情况
    public void displayFreePartitions() {
        Partition current = head;
        System.out.println("空闲分区链情况：");
        while (current != null) {
            if (current.isFree) {
                System.out.println(current);
            }
            current = current.next;
        }
    }

    // 首次适应算法
    public void firstFit(int size) {
        Partition current = head;
        while (current != null) {
            if (current.isFree && current.size >= size) {
                allocatePartition(current, size);
                return;
            }
            current = current.next;
        }
        System.out.println("首次适应算法：无法分配 " + size + "KB 内存");
    }

    // 循环首次适应算法
    public void nextFit(int size) {
        Partition current = lastAllocated;
        do {
            if (current.isFree && current.size >= size) {
                allocatePartition(current, size);
                lastAllocated = current;
                return;
            }
            current = (current.next != null) ? current.next : head;
        } while (current != lastAllocated);
        System.out.println("循环首次适应算法：无法分配 " + size + "KB 内存");
    }

    // 最佳适应算法
    public void bestFit(int size) {
        Partition best = null;
        Partition current = head;
        while (current != null) {
            if (current.isFree && current.size >= size) {
                if (best == null || current.size < best.size) {
                    best = current;
                }
            }
            current = current.next;
        }
        if (best != null) {
            allocatePartition(best, size);
        } else {
            System.out.println("最佳适应算法：无法分配 " + size + "KB 内存");
        }
    }

    // 分配分区
    private void allocatePartition(Partition partition, int size) {
        if (partition.size > size) {
            Partition newPartition = new Partition(partition.startAddress + size, partition.size - size, true);
            newPartition.next = partition.next;
            newPartition.prev = partition;
            if (partition.next != null) {
                partition.next.prev = newPartition;
            }
            partition.next = newPartition;
            partition.size = size;
        }
        partition.isFree = false;
        System.out.println("分配 " + size + "KB 内存，起始地址：" + partition.startAddress);
    }

    // 回收分区
    public void freePartition(int startAddress) {
        Partition current = head;
        while (current != null) {
            if (current.startAddress == startAddress && !current.isFree) {
                current.isFree = true;
                mergeFreePartitions(current);
                System.out.println("释放内存，起始地址：" + startAddress);
                return;
            }
            current = current.next;
        }
        System.out.println("未找到需要释放的内存，起始地址：" + startAddress);
    }

    // 合并相邻的空闲分区
    private void mergeFreePartitions(Partition partition) {
        if (partition.prev != null && partition.prev.isFree) {
            partition.prev.size += partition.size;
            partition.prev.next = partition.next;
            if (partition.next != null) {
                partition.next.prev = partition.prev;
            }
            partition = partition.prev;
        }
        if (partition.next != null && partition.next.isFree) {
            partition.size += partition.next.size;
            partition.next = partition.next.next;
            if (partition.next != null) {
                partition.next.prev = partition;
            }
        }
    }
}